#!/usr/bin/env bash

# Use this to build -fPIC C or C++ code using zig.   I like doing this, since zig is a very
# compact and efficient way to CLANG/LLVM.  Unfortunately (in mid 2022), zig doesn't directly
# support building -fPIC code (the flag does nothing), which is of course absolutely required
# to create and use a dynamic library with WebAssembly.   Fortunately, zig includes wasm-ld
# and clang, so we can work around this shortcoming.  This script does so, basically by
# add a bunch of obscure options to the command line.
#
# TODO: upstream this by improving the way zig handles -target=wasm32-emscripten, or
# some other approach.
#

# Needed on macOS
realpath() {
  OURPWD=$PWD
  cd "$(dirname "$1")"
  LINK=$(readlink "$(basename "$1")")
  while [ "$LINK" ]; do
    cd "$(dirname "$LINK")"
    LINK=$(readlink "$(basename "$1")")
  done
  REALPATH="$PWD/$(basename "$1")"
  cd "$OURPWD"
  echo "$REALPATH"
}

ZIG_EXE=`which zig`
ZIG_EXE=`realpath $ZIG_EXE`
ZIG_HOME=`dirname $ZIG_EXE`

#echo "ZIG_EXE=$ZIG_EXE"

INCLUDE="$ZIG_HOME/lib/zig/libc/include"

# On MacOS the includes are in $ZIG_HOME/lib/zig/libc (etc), for some reason
# on Linux it is just $ZIG_HOME/lib/libc, i.e., sometimes there's an extra zig in the path.

if [ ! -d "$INCLUDE" ]
then
    INCLUDE="$ZIG_HOME/lib/libc/include"
fi
#echo "INCLUDE=$INCLUDE"

# These are the flags we need to make the -target=wasm32-emscripten actually work
# with what's provided in the zig distribution.   Note that we always set -shared,
# the target wasm32-emscripten and -fPIC, since I can't think
# of any reason to be using this script when you wouldn't have those set.

FLAGS="\
    -target wasm32-emscripten \
    -fPIC \
    -isystem $INCLUDE/wasm-wasi-musl \
    -isystem $INCLUDE/generic-musl \
    -D__wasi__ -D__EMSCRIPTEN_major__=3 -D__EMSCRIPTEN_minor__=1 -D__EMSCRIPTEN_tiny__=16 \
    -D_WASI_EMULATED_MMAN -D_WASI_EMULATED_SIGNAL -D_WASI_EMULATED_PROCESS_CLOCKS -D_WASI_EMULATED_GETPID"

echo "zig $@ $FLAGS"
zig "$@" $FLAGS
